//
//  NSObject+Archiver.m
//  ITC_iOS
//
//  Created by Benz.L on 03/09/2018.
//  Copyright © 2018 Benz.L. All rights reserved.
//

#import "NSObject+Archiver.h"
#import <objc/runtime.h>

@interface NSObject()<NSCopying>
@end
@implementation NSObject(Archiver)

+ (instancetype)unarchive:(NSData *)data {
    return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

- (NSData *)archive {
    return [NSKeyedArchiver archivedDataWithRootObject:self];
}

#pragma mark - 直接添加以下代码即可自动完成序列化／反序列化
//- (void)encodeWithCoder:(NSCoder *)aCoder {
//    [self yy_modelEncodeWithCoder:aCoder];
//}
//- (id)initWithCoder:(NSCoder *)aDecoder {
////    self = [super init];
//    return [self yy_modelInitWithCoder:aDecoder];
//}
//- (id)copyWithZone:(NSZone *)zone {
//    return [self yy_modelCopy];
//}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [self bl_encodeWithCoder:aCoder];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    //    self = [super init];
    return [self bl_initWithCoder:aDecoder];
}
- (id)copyWithZone:(NSZone *)zone {
    return [self bl_copyWithZone:zone];
}

@end


@implementation NSObject (BLCoding_Copying)

- (void)bl_encodeWithCoder:(NSCoder *)aCoder {
    for (NSString *key in self.allProperties) {
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
}
- (id)bl_initWithCoder:(NSCoder *)aDecoder {
    for (NSString *key in self.allProperties) {
        id value = [aDecoder decodeObjectForKey:key];
        [self setValue:value forKey:key];
    }
    return self;
}
- (id)bl_copyWithZone:(NSZone *)zone {
    id obj = [[self.class allocWithZone:zone] init];
    for (NSString *key in self.allProperties) {
        id value = [[self valueForKey:key] copyWithZone:zone];
        [obj setValue:value forKey:key];
    }
    return obj;
}

- (NSArray *)allProperties {
    NSMutableArray *arr = [NSMutableArray arrayWithCapacity:0];
    Class cls = self.class;
    while (cls && cls.superclass) { //排除NSObject
        unsigned int outCount;
        int i;
        objc_property_t *pProperty = class_copyPropertyList(cls, &outCount);
        for (i = 0; i < outCount; i++){
            NSString *getPropertyName = [NSString stringWithCString:property_getName(pProperty[i]) encoding:NSUTF8StringEncoding];
            NSString *getPropertyNameString = [NSString stringWithCString:property_getAttributes(pProperty[i]) encoding:NSUTF8StringEncoding];
            //NSLog(@"%@====%@",getPropertyNameString,getPropertyName);
            //非readonly
            if (![getPropertyNameString rangeOfString:@"R"].length) {
                //属性类型参考 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW24
                [arr addObject:getPropertyName];
            }
        }
        cls = class_getSuperclass(cls);
    }
    //NSLog(@"class=%@, %@", NSStringFromClass(self.class), arr);
    return arr;
}
@end
